<?php
/**
 * Created by PhpStorm.
 * User: lf
 * Date: 2018/1/12
 * Time: 17:33
 */

namespace AppBundle\Service;

use AppBundle\Service\lib\IAuth;
use AppBundle\Service\lib\Aes;
use AppBundle\Service\lib\Time;
/**
 * Class CommonService
 * @package AppBundle\Service
 * @abstract 通用函数的服务类，其中对应的函数是自定义的一些通用函数，在控制器的任何地方都可能使用到
 */
class CommonService{


    /**
     * @abstract redis的访问ip
     * @var string
     */
    private $_strRedisHost = '';


    /**
     * @abstract redis的访问端口
     * @var string
     */
    private $_sreRedisPort = '';


    /**
     * @abstract api请求的时间限制
     * @var int
     */
    private $_intDeadTime = 10;


    /**
     * CommonService constructor.
     * @param $__strRedisHost  redis的访问ip
     * @param $__strRedisPort  redis的开启端口
     */
    public function __construct($__strRedisHost,$__strRedisPort,$__intDeadTime)
    {
        $this->_sreRedisPort = $__strRedisPort;
        $this->_strRedisHost = $__strRedisHost;
        $this->_intDeadTime = $__intDeadTime;
    }


    /**
     * @author lf
     * @param $arrData 待处理的数组
     * @abstract 在页面上拼接字符串的时候‘&’字符串在html中会被转义为‘&amp;’，这个函数就是为了处理在控制器中获得了参数传递之后
     * 将对应的'&amp;'转换为‘&’
     */
    public function build_query($arrData){
        foreach($arrData as $key=>$value){
            if(strpos($key,'amp;') !== false){//存在
                $_strNewKey = str_replace('amp;','',$key);
                $arrData[$_strNewKey] = $value;
                unset($arrData[$key]);
            }
        }
        return $arrData;
    }

    /**
     * @abstract api接口返回的统一封装函数
     * @param $intStatus  业务状态码
     * @param $strMessage 描述信息
     * @param $arrData 数据
     * @param int $intHttpCode http状态码
     */
    public function apiEnCode($intStatus,$strMessage,$arrData,$intHttpCode = 200){
        //封装返回数据
        $arrReturnData = array(
            'status' => $intStatus,
            'message' => $strMessage,
            'data' => $arrData,
            'httpcode' => $intHttpCode
        );
        return json_encode($arrReturnData);
    }


    /**
     * @abstract 加密sign的函数
     * @param $arrData
     * @return string
     */
    public function encryptSign($arrData){
        $_objIAuth = new IAuth();
        $_strSign = $_objIAuth->setSign($arrData);
        return $_strSign;
    }

    /**
     * @abstract 解密sign的函数
     * @param $strString
     * @return String
     */
    public function decryptSign($strString){
        $_objAes = new Aes();
        $_strString  = $_objAes->decrypt($strString);
        return $_strString;
    }


    /**
     * @abstract 校验sign的合法性
     * @param $data
     * @return bool
     */
    public function checkSignPass($data){
        //首先解密发送过来的sign
        $strSign = $this->decryptSign($data->get('sign'));
        if(empty($strSign)){//sign验签为空
            return false;
        }
        //判断sign解密的参数值是都和传递的参数值是一致的
        parse_str($strSign,$arrData);
        if(!is_array($arrData) || empty($arrData['did']) || $data->get('did') != $arrData['did']){
            return false;
        }
        //还需要校验时间戳，也就是这个请求需要在规定时间内获得响应否则就失效
        if((time() - ceil($arrData['time']/1000)) > $this->_intDeadTime){
            return false;
        }

        return true;
    }

    /**
     * @abstract 获取13位的时间戳
     * @return int
     */
    public function get13TimeStamp(){
        return Time::get13TimeStamp();
    }


    /**
     * @abstract 使用redis存储验签sign的值
     * @param $request
     * @return int
     */
    function saveSignByRedis($request){
        $_objHeader = $request->headers;
        $redis = new \Redis();
        $redis->connect($this->_strRedisHost, $this->_sreRedisPort);
        $_strSign = $_objHeader->get('sign');
        //首先判断是否存在在集合中不存在的情况下新增一下
        if($redis->sIsMember('all_request',$_strSign)){//已经存在那么不在存储这条记录同时说明请求不合法
            return false;
        }else{
            $intCount = $redis->sAdd('all_request',$_strSign);
            if($intCount != 0){//说明成功的新增
                return true;
            }else{
                return false;
            }
        }
    }


}